#pragma once

#include "TypeTraits.h"
#include "Assert.h"

namespace MockItNow
{
	template<typename T>
	struct Storage
	{
		Storage(const T& value_)
		: value(value_),
		  address(&value_)
		{
			MOCKITNOW_STATIC_ASSERT(IsReference<T>::Value == false, ArgumentTypeIsAReference);
			MOCKITNOW_STATIC_ASSERT(IsConst<T>::Value == false, ArgumentTypeIsConst);
		}

		Storage(const T* address_)
		: value(*address_),
		  address(address_)
		{
			MOCKITNOW_STATIC_ASSERT(IsReference<T>::Value == false, ArgumentTypeIsAReference);
			MOCKITNOW_STATIC_ASSERT(IsConst<T>::Value == false, ArgumentTypeIsConst);
		}

		T value;
		const T* address;

	private:

		Storage(const Storage&);
		Storage& operator=(const Storage&);
	};

	template<>
	struct Storage<char *>
	{
		Storage(const char* value_)
		{
			value = new char[strlen(value_) + 1];
			strcpy(value, value_);
		}

		~Storage()
		{
			delete[] value;
		}

		char* value;

	private:

		Storage(const Storage&);
		Storage& operator=(const Storage&);
	};
}
